/*
* Nettle Source File.
* Copyright (C) 2013, Nettle (http://nttl.ru/).
*
* This file is part of NettleMath.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Lesser General Public License
* (LGPL) version 2.1 which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/lgpl-2.1.html
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* Description:
*
* History:
* Created by Sergey Serb, l-proger@yandex.ru
*/

#ifndef NBoundingBox_h__
#define NBoundingBox_h__

#include "NVector3.h"
#include <limits>

namespace NettleMath{
    template<typename T>
    struct NBoundingBox{
        NVector3<T> vmin;
        NVector3<T> vmax;

        NBoundingBox()
            : vmin( std::numeric_limits<T>::max(), std::numeric_limits<T>::max(), std::numeric_limits<T>::max()),
            vmax(-std::numeric_limits<T>::max(),-std::numeric_limits<T>::max(),-std::numeric_limits<T>::max())
        {
        }

        NBoundingBox(const NVector3<T>& umin, const NVector3<T>& umax)
            : vmin(umin), vmax(umax)
        {
        }

        const NVector3<T> GetSize() const{
            return vmax - vmin;
        }

        bool IsInside(const NVector3<T>& point) const
        {
            if ( point.x < vmin.x || point.y < vmin.y || point.z < vmin.z ) return false;
            if ( point.x > vmax.x || point.y > vmax.y || point.z > vmax.z ) return false;
            return true;
        }

        const NVector3<T> GetCenter() const{
            return (vmax + vmin) / static_cast<T>(2);
        }

        void GetVertexArray8(NVector3<T> vertex[]) const
        {
            vertex[0] = NVector3<T>(vmin.x,vmin.y,vmin.z);
            vertex[1] = NVector3<T>(vmax.x,vmin.y,vmin.z);
            vertex[2] = NVector3<T>(vmin.x,vmax.y,vmin.z);
            vertex[3] = NVector3<T>(vmax.x,vmax.y,vmin.z);
            vertex[4] = NVector3<T>(vmin.x,vmin.y,vmax.z);
            vertex[5] = NVector3<T>(vmax.x,vmin.y,vmax.z);
            vertex[6] = NVector3<T>(vmin.x,vmax.y,vmax.z);
            vertex[7] = NVector3<T>(vmax.x,vmax.y,vmax.z);
        }
    };

    typedef NBoundingBox<float> box3f;
    typedef NBoundingBox<double> box3d;
    typedef NBoundingBox<int> box3i;
}
#endif // NBoundingBox_h__
